{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "z = [\"asd\"]\n",
    "def hello():\n",
    "    asd = [z] # Definition of a bound free variable\n",
    "    return asd\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'z': ['asd']}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'z': ['f']}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from dill.detect import globalvars, freevars, nestedglobals, outermost, nestedcode\n",
    "y= globalvars(hello)\n",
    "print(y)\n",
    "z[0] = \"f\"\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'z': 'asdasda asdasdasd asdasdasdasd', 'h': 'h'}\n",
      "{}\n",
      "{}\n"
     ]
    }
   ],
   "source": [
    "y = (outermost(testfn))\n",
    "for x in [y] + nestedcode(y):\n",
    "    print(globalvars(x))\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "module, class, method, function, traceback, frame, or code object was expected, got str",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "File \u001b[0;32m/opt/homebrew/Caskroom/miniconda/base/envs/ell/lib/python3.12/site-packages/dill/source.py:157\u001b[0m, in \u001b[0;36mfindsource\u001b[0;34m(object)\u001b[0m\n\u001b[1;32m    156\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m isclass(\u001b[38;5;28mobject\u001b[39m) \u001b[38;5;129;01mand\u001b[39;00m isclass(\u001b[38;5;28mtype\u001b[39m(\u001b[38;5;28mobject\u001b[39m)): \u001b[38;5;66;03m# __class__\u001b[39;00m\n\u001b[0;32m--> 157\u001b[0m     file \u001b[38;5;241m=\u001b[39m \u001b[43mgetfile\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodule\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    158\u001b[0m     sourcefile \u001b[38;5;241m=\u001b[39m getsourcefile(module)\n",
      "File \u001b[0;32m/opt/homebrew/Caskroom/miniconda/base/envs/ell/lib/python3.12/inspect.py:929\u001b[0m, in \u001b[0;36mgetfile\u001b[0;34m(object)\u001b[0m\n\u001b[1;32m    928\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mobject\u001b[39m\u001b[38;5;241m.\u001b[39mco_filename\n\u001b[0;32m--> 929\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmodule, class, method, function, traceback, frame, or \u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m    930\u001b[0m                 \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcode object was expected, got \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m    931\u001b[0m                 \u001b[38;5;28mtype\u001b[39m(\u001b[38;5;28mobject\u001b[39m)\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m))\n",
      "\u001b[0;31mTypeError\u001b[0m: module, class, method, function, traceback, frame, or code object was expected, got NoneType",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[78], line 2\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mdill\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01msource\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;241m*\u001b[39m\n\u001b[0;32m----> 2\u001b[0m \u001b[43mfindsource\u001b[49m\u001b[43m(\u001b[49m\u001b[43mglobalvars\u001b[49m\u001b[43m(\u001b[49m\u001b[43my\u001b[49m\u001b[43m)\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mz\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m/opt/homebrew/Caskroom/miniconda/base/envs/ell/lib/python3.12/site-packages/dill/source.py:163\u001b[0m, in \u001b[0;36mfindsource\u001b[0;34m(object)\u001b[0m\n\u001b[1;32m    161\u001b[0m         sourcefile \u001b[38;5;241m=\u001b[39m getsourcefile(\u001b[38;5;28mobject\u001b[39m)\n\u001b[1;32m    162\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mTypeError\u001b[39;00m, \u001b[38;5;167;01mAttributeError\u001b[39;00m): \u001b[38;5;66;03m# fail with better error\u001b[39;00m\n\u001b[0;32m--> 163\u001b[0m     file \u001b[38;5;241m=\u001b[39m \u001b[43mgetfile\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mobject\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m    164\u001b[0m     sourcefile \u001b[38;5;241m=\u001b[39m getsourcefile(\u001b[38;5;28mobject\u001b[39m)\n\u001b[1;32m    165\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m sourcefile \u001b[38;5;129;01mand\u001b[39;00m file[:\u001b[38;5;241m1\u001b[39m] \u001b[38;5;241m+\u001b[39m file[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m:] \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m<>\u001b[39m\u001b[38;5;124m'\u001b[39m:\n",
      "File \u001b[0;32m/opt/homebrew/Caskroom/miniconda/base/envs/ell/lib/python3.12/inspect.py:929\u001b[0m, in \u001b[0;36mgetfile\u001b[0;34m(object)\u001b[0m\n\u001b[1;32m    927\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m iscode(\u001b[38;5;28mobject\u001b[39m):\n\u001b[1;32m    928\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mobject\u001b[39m\u001b[38;5;241m.\u001b[39mco_filename\n\u001b[0;32m--> 929\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mmodule, class, method, function, traceback, frame, or \u001b[39m\u001b[38;5;124m'\u001b[39m\n\u001b[1;32m    930\u001b[0m                 \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcode object was expected, got \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\n\u001b[1;32m    931\u001b[0m                 \u001b[38;5;28mtype\u001b[39m(\u001b[38;5;28mobject\u001b[39m)\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m))\n",
      "\u001b[0;31mTypeError\u001b[0m: module, class, method, function, traceback, frame, or code object was expected, got str"
     ]
    }
   ],
   "source": [
    "from dill.source import *\n",
    "findsource(globalvars(y)['z'])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. Get the global variables referenced by all enclosing scopes "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "ell",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
